package com.ayoka.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import com.ayoka.R;
import com.jcp.baselibrary.utils.UIUtils;

/**
 * Created by admin on 17/10/26.
 */

public class RuleSeekBar extends View {
    private static final float PADDING = UIUtils.getDimensionPixelSize(R.dimen.dp_12);
    private Paint mLinePaint;
    private Paint mProcessPaint;
    private Paint mRulerPaint;
    private Paint mTextPaint;
    //当前的位置
    private int process = 1;
    private int maxProcess = 10;
    private int minProcess = 0;
    private boolean isCanMove;
    //process的颜色
    private int processColor;
    //background的颜色
    private int backgroundColor;
    //一个单元格的单位
    private int oneItemValue = 1;
    //一个单元格的宽度
    private float widthOfItem;
    //总共多少格
    private int numberOfItem;
    //标尺宽度
    private float widthOfProgress;
    //线的宽度
    private float widthOfLine;
    //标尺的高度
    private float markerHeight;
    //标尺的位置
    private float xProgress;
    //游标的边长
    private float cursorLength;
    //空余的边长
    private float paddingContent = PADDING;
    //能不能滑动到中间
    private boolean scrollable = true;

    private OnRangeRulerChangeListener onRangeRulerChangeListener;

    public void setOnRangeRulerChangeListener(OnRangeRulerChangeListener onRangeRulerChangeListener) {
        this.onRangeRulerChangeListener = onRangeRulerChangeListener;
    }

    public RuleSeekBar(Context context) {
        this(context, null);
    }

    public RuleSeekBar(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RuleSeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray types = context.obtainStyledAttributes(attrs, R.styleable.RuleSeekBar, 0, 0);
        backgroundColor = types.getColor(R.styleable.RuleSeekBar_RSB_background_color, Color.GRAY);
        processColor = types.getColor(R.styleable.RuleSeekBar_RSB_process_color, Color.BLUE);
        maxProcess = types.getInteger(R.styleable.RuleSeekBar_RSB_max_progress, maxProcess);
        minProcess = types.getInteger(R.styleable.RuleSeekBar_RSB_min_progress, minProcess);
        process = types.getInteger(R.styleable.RuleSeekBar_RSB_current_progress, process);
        widthOfLine = types.getFloat(R.styleable.RuleSeekBar_RSB_line_width, 2);
        markerHeight = types.getFloat(R.styleable.RuleSeekBar_RSB_marker_height, 20);
        cursorLength = types.getFloat(R.styleable.RuleSeekBar_RSB_cursor_length, 40);
        paddingContent = types.getFloat(R.styleable.RuleSeekBar_RSB_padding_content, PADDING);
        xProgress = paddingContent;
        scrollable = types.getBoolean(R.styleable.RuleSeekBar_RSB_scrollable, scrollable);

        types.recycle();
        init();

    }

    private void init() {
        //线的画笔
        mLinePaint = new Paint();
        mLinePaint.setColor(backgroundColor);
        mLinePaint.setAntiAlias(true);//抗锯齿
        mLinePaint.setStyle(Paint.Style.FILL);//设置画笔样式(Stroke空心,Fill实心)
        mLinePaint.setStrokeWidth(widthOfLine);

        //进度条的画笔
        mProcessPaint = new Paint();
        mProcessPaint.setColor(processColor);
        mProcessPaint.setAntiAlias(true);//抗锯齿
        mProcessPaint.setStyle(Paint.Style.STROKE);//设置画笔样式(Stroke空心,Fill实心)
        mProcessPaint.setStrokeWidth(widthOfLine);

        //标尺的画笔
        mRulerPaint = new Paint();
        mRulerPaint.setColor(processColor);
        mRulerPaint.setAntiAlias(true);
        mRulerPaint.setStyle(Paint.Style.FILL);
        mRulerPaint.setStrokeWidth(widthOfLine);

        //标尺的画笔
        mTextPaint = new Paint();
        mTextPaint.setColor(processColor);
        mTextPaint.setAntiAlias(true);
        mTextPaint.setStyle(Paint.Style.FILL);
        mTextPaint.setTextSize(UIUtils.getDimensionPixelSize(R.dimen.text_size_20));
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        final int height = getDefaultSize(getSuggestedMinimumHeight(),
                heightMeasureSpec);
        final int width = getDefaultSize(getSuggestedMinimumWidth(),
                widthMeasureSpec);
        int w = resolveSize(width, widthMeasureSpec);
        int h = resolveSize(height, heightMeasureSpec);
        setMeasuredDimension(w, h);

        numberOfItem = (maxProcess - minProcess) / oneItemValue;
        widthOfItem = (w - paddingContent - paddingContent) / numberOfItem;
        //总宽减去线的宽度
        widthOfProgress = widthOfItem * numberOfItem + paddingContent;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawMarker(canvas);
        drawProgressBar(canvas);
        drawCursor(canvas);
        drawText(canvas);
    }

    private void drawText(Canvas canvas) {
        //2. 计算文字所在矩形，可以得到宽高
        int left = (int) (xProgress - UIUtils.getDimensionPixelSize(R.dimen.dp_25) / 2);
        int top = (int) (markerHeight + widthOfLine + cursorLength);
        int right = (int) (left + UIUtils.getDimensionPixelSize(R.dimen.dp_24));
        int bottom = (int) (top + UIUtils.getDimensionPixelSize(R.dimen.dp_24));
        Rect rect = new Rect(left, top, right, bottom);//画一个矩形
        String text = String.valueOf(process);
        //该方法即为设置基线上那个点究竟是left,center,还是right  这里我设置为center
        mTextPaint.setTextAlign(Paint.Align.CENTER);
        Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();
        float marginTop = fontMetrics.top;//为基线到字体上边框的距离,即上图中的top
        float marginBottom = fontMetrics.bottom;//为基线到字体下边框的距离,即上图中的bottom
        int baseLineY = (int) (rect.centerY() - marginTop / 2 - marginBottom / 2);//基线中间点的y轴计算公式
        canvas.drawText(String.valueOf(text), rect.centerX(), baseLineY, mTextPaint);
    }

    private void drawCursor(Canvas canvas) {
//        //画红线游标
//        canvas.drawLine(xProgress, getHeight() / 2, xProgress, getHeight(), mRulerPaint);
        //画三角形游标
        Path triangle = new Path();
        //triangle
        triangle.moveTo(xProgress, markerHeight + widthOfLine);
        //从起始位置划线到p1坐标
        triangle.lineTo(xProgress - cursorLength / 2, markerHeight + widthOfLine + UIUtils.getDimensionPixelSize(R.dimen.dp_15));
        //从p1位置划线到p2坐标
        triangle.lineTo(xProgress + cursorLength / 2, markerHeight + widthOfLine +  + UIUtils.getDimensionPixelSize(R.dimen.dp_15));
        //将mpath封闭，也可以写 mpath.lineTo(100, 100);代替
        triangle.close();
        //绘制path路径
        canvas.drawPath(triangle, mRulerPaint);
    }

    private void drawProgressBar(Canvas canvas) {
        // 背景色
        canvas.drawLine(paddingContent, markerHeight - widthOfLine / 2, widthOfProgress, markerHeight - widthOfLine / 2, mLinePaint);
        // 进度条色
        canvas.drawLine(paddingContent, markerHeight - widthOfLine / 2, xProgress + widthOfLine, markerHeight - widthOfLine / 2, mProcessPaint);
    }

    private void drawMarker(Canvas canvas) {
        canvas.save();
        for (int i = minProcess; i <= maxProcess; i = i + oneItemValue) {
            if (i <= process) {
                mLinePaint.setColor(processColor);
            } else {
                mLinePaint.setColor(backgroundColor);
            }
            canvas.drawLine(paddingContent, 0, paddingContent, markerHeight, mLinePaint);
            //每隔一个单位像素移动一次达到划线效果
            canvas.translate(widthOfItem, 0);
        }
        canvas.restore();
    }

    // 分别记录上次滑动的坐标(onInterceptTouchEvent)
    private int mLastXIntercept = 0;
    private int mLastYIntercept = 0;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (!isEnabled()) return false;
        int x = (int) event.getX();
        int y = (int) event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_POINTER_DOWN:
                if (x > paddingContent + widthOfProgress || x < paddingContent) {
                    isCanMove = false;
                } else {
                    isCanMove = true;
                }
                break;
            case MotionEvent.ACTION_MOVE:
                if (!isCanMove) {
                    return false;
                }
                if (x < paddingContent || x > widthOfProgress) {
                    return false;
                }
                int deltaX = x - mLastXIntercept;
                int deltaY = y - mLastYIntercept;
                //如果是左右滑动
                if (Math.abs(deltaX) > Math.abs(deltaY)) {
                    getParent().requestDisallowInterceptTouchEvent(true);
                } else {
                    return false;
                }
                if (scrollable) {
                    xProgress = x;
                    process = minProcess + Math.round((xProgress - paddingContent) / widthOfItem) * oneItemValue;
                    if (onRangeRulerChangeListener != null) {
                        onRangeRulerChangeListener.onValueChanged(process);
                    }
                    invalidate();
                } else {
                    if (x < widthOfProgress / 2) {
                        xProgress = paddingContent;
                    } else {
                        xProgress = widthOfProgress;
                    }
                    process = minProcess + Math.round((xProgress - paddingContent) / widthOfItem) * oneItemValue;
                    if (onRangeRulerChangeListener != null) {
                        onRangeRulerChangeListener.onValueChanged(process);
                    }
                    invalidate();

                }

                break;
            case MotionEvent.ACTION_POINTER_UP:
            case MotionEvent.ACTION_UP:
                getParent().requestDisallowInterceptTouchEvent(false);
                float x1 = event.getX();
                if (scrollable) {
                    int number = Math.round((x1 - paddingContent) / widthOfItem);
                    if (number < 0) {
                        number = 0;

                    } else if (number >= numberOfItem) {
                        number = numberOfItem;
                    }
                    xProgress = paddingContent + number * widthOfItem;
                    invalidate();
                } else {

                    if (x1 >= widthOfProgress / 2) {
                        xProgress = paddingContent + numberOfItem * widthOfItem;
                    } else {
                        xProgress = paddingContent;
                    }
                    invalidate();
                }
                process = minProcess + Math.round((xProgress - paddingContent) / widthOfItem) * oneItemValue;
                if (onRangeRulerChangeListener != null) {
                    onRangeRulerChangeListener.onValueChanged(process);
                }
                break;
        }
        mLastXIntercept = x;
        mLastYIntercept = y;
        return true;
    }

    public int getCurrentProgress() {
        return process;
    }

    //设置当前位置，传值为标尺上的刻度
    //设置当前值一定要在设置了监听之后
    public void setCurrentProgress(final int currentProgress) {
        post(new Runnable() {
            @Override
            public void run() {
                RuleSeekBar.this.process = currentProgress;
                xProgress = paddingContent + currentProgress * widthOfItem;
                invalidate();
                if (onRangeRulerChangeListener != null) {
                    onRangeRulerChangeListener.onValueChanged(process);
                }
            }
        });
    }

    public interface OnRangeRulerChangeListener {
        void onValueChanged(int value);
    }
}
